#include "MySQLite.h"
#include "loop_ifc.h"

std::shared_ptr<MySQLite> MySQLite::m_pInstance = nullptr;

void MySQLite::queryWrapper(const std::string&tableName, std::vector <std::string>& colName, const std::string& condition, Callback cb)
{
    std::shared_ptr<Loop::Loop_Ifc> pLoop = Loop::Loop_Ifc::Create();
    pLoop->CallInLoop( std::bind(&MySQLite::query, shared_from_this(), tableName, colName, condition, cb));  // 加上本类一个对象或指针
}

// 表名  列名  查询条件
void MySQLite::query(const std::string& tableName, std::vector<std::string>& colName, const std::string& condition, Callback cb) const
{
    json table;
    if ("*" == colName[0])
    {
        // 1、SELECT *
        table = queryStar(tableName, condition);
    }
    else
    {
        // 2、其他 SELECT 语句
        table = queryNormal(tableName, colName, condition);
    }

    if (cb) // 指针 判空
    {
        cb(table);
    }

    //"SELECT column1, column2, columnN FROM table_name WHERE weight > ?"
}

void MySQLite::insert(const std::string& tableName, std::vector<std::string>& colName, json& values)
{
    std::string statement = "INSERT INTO " + tableName;

    // 表名字段拼接
    if (colName.size() != 0)
    {
        statement += " (";
        for (auto &col : colName)
        {
            statement += std::string(" \"") + col + "\"" + ",";
        }
        statement.pop_back();
        statement += ") ";
    }

    statement += std::string(" VALUES ") + "(";
    // 解析json
    for (auto &elem : values)
    {
        // std::cout << elem << std::endl;
        if (elem.is_number())
        { // json的函数
            int x = elem;
            statement += std::to_string(x) + ",";
        }
        else if (elem.is_number_float())
        {
            float f = elem;
            statement += std::to_string(f) + ",";
        }
        else if (elem.is_string())
        {
            std::string x = elem;
            statement += std::string(" \"") + x + "\"" + ",";
        }
    }
    statement.pop_back();
    statement += ");";
    // std::cout << statement << std::endl;  // 打印语句
    int nb = m_Db.exec(statement);
    if (0 == nb)
    {
        std::cout << "result: "
                  << "error!" << std::endl;
    }
    else
    {
        // std::cout << "result: " << nb << std::endl;
    }
}

void MySQLite::deleteValue(const std::string& tableName, const std::string& condition)
{
    const std::string statement = "DELETE FROM " + tableName + " WHERE " + condition + ";";
    int nb = m_Db.exec(statement);
    std::cout << "result: " << nb << std::endl;
}

json MySQLite::queryNormal(const std::string& tableName, std::vector<std::string>& colName, const std::string& condition) const
{
    std::string statement = "SELECT";
    for (auto &elem : colName)
    {
        statement += " " + elem + ",";
    }
    statement.pop_back();

    statement += std::string(" ") + "FROM" + " " + tableName; //
    if ("" == condition)
    {
        statement += ";";
    }
    else
    {
        statement += std::string(" ") + "WHERE" + " " + condition;
    }
    // std::cout << statement << std::endl;  // 打印语句

    json table;

    // statement:  SQLite::Statement
    SQLite::Statement query(m_Db, statement); // Datebase prepared SQL query

    int row = 1; //
    while (query.executeStep())
    {
        std::string rowStr = std::to_string(row); // string 类型
        // const int         id     = query.getColumn("test_id");
        // 查询一行的结果
        for (auto &elem : colName)
        {
            SQLite::Column column = query.getColumn(elem.c_str());
            if (column.isInteger())
            {
                const int x = column;
                table[rowStr].emplace_back(x);
            }
            else if (column.isFloat())
            {
                const double x = column; // operator double() const
                table[rowStr].emplace_back(x);
            }
            else if (column.isText())
            {
                const std::string x = column;
                table[rowStr].emplace_back(x);
            }
            else if (column.isBlob())
            {
                const std::string x = column;
                table[rowStr].emplace_back(x);
            }
            else
            {
                const std::string x = ""; // nullptr
                continue;
            }
        }
        // 一行查询完成
        ++row;
    }
    return table;
}

json MySQLite::queryStar(const std::string& tableName, const std::string& condition) const
{
    // "SELECT * FROM test"
    std::string statement = std::string("SELECT * FROM ") + tableName;
    if ("" == condition)
    {
        statement += std::string(";");
    }
    else
    {
        statement += std::string(" ") + "WHERE" + " " + condition;
    }
    // std::cout << statement <<  std::endl;   // 打印语句

    // Check the results : expect two row of result
    SQLite::Statement query(m_Db, statement);
    // std::cout << "colCount: " << query.getColumnCount() << std::endl;
    int colCount = query.getColumnCount(); // 获取列数
    json table;
    int row = 1; //
    while (query.executeStep())
    {
        std::string rowStr = std::to_string(row);
        for (int col = 0; col < colCount; ++col)
        {
            SQLite::Column column = query.getColumn(col);
            if (column.isInteger())
            {
                const int x = column;
                table[rowStr].emplace_back(x);
            }
            else if (column.isFloat())
            {
                const double x = column; // operator double() const
                table[rowStr].emplace_back(x);
            }
            else if (column.isText())
            {
                const std::string x = column;
                table[rowStr].emplace_back(x);
            }
            else if (column.isBlob())
            {
                const std::string x = column;
                table[rowStr].emplace_back(x);
            }
            else
            {
                const std::string x = ""; // nullptr
                continue;
            }
        }
        ++row;
    }
    return table;
}